package com.ece.devirtualizus.Services;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import com.ece.devirtualizus.Dao.SqlLiteProgressBarDao;
import com.ece.devirtualizus.Detectors.DetectorInterface;
import com.ece.devirtualizus.Entities.StepEntity;
import com.ece.devirtualizus.ModelDto.Modules;

import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.IBinder;
import android.util.Log;

public class StepService extends Service implements SensorEventListener,
		DetectorInterface {

	SensorManager sensorManager;
	private SqlLiteProgressBarDao sqlLiteProgressBarDao;

	private final static String TAG = "StepDetector";
	private float mLimit = 20;
	private float mLastValues[] = new float[3 * 2];
	private float mScale[] = new float[2];
	private float mYOffset;

	private float mLastDirections[] = new float[3 * 2];
	private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] };
	private float mLastDiff[] = new float[3 * 2];
	private int mLastMatch = -1;
	private int _count = 0;

	public final static String MY_ACTION = "MY_ACTION";

	@Override
	public void onSensorChanged(SensorEvent arg0) {
		if (arg0.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
			synchronized (this) {
				this.getDetectorValues(arg0);
			}
		}
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		sqlLiteProgressBarDao = new SqlLiteProgressBarDao(this);
		sqlLiteProgressBarDao.open();
		ArrayList<StepEntity> listStep = sqlLiteProgressBarDao.getLastStepCount();
		_count = 0;
		for(int i=0;i<listStep.size();i++)
		{
			_count = _count + listStep.get(i).getCount();
		}		
		Log.d("-------STEP COUNT------",Integer.toString(_count));
		
		MyThread t = new MyThread();
		t.start();
		return Service.START_STICKY;
	}

	public class MyThread extends Thread {
		@Override
		public void run() {
			Log.d("-------STEP SERVICE-------", "START ");
			startDetection();
		}

	}

	@Override
	public void startDetection() {
		Log.d("STEP SERVICE", "START STEP COUNTER");
		sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		sensorManager.registerListener(this,
				sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
				SensorManager.SENSOR_DELAY_FASTEST);

		int h = 480; // TODO: remove this constant
		mYOffset = h * 0.5f;
		mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
		mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
	}

	@Override
	public void onRebind(Intent intent) {
		Log.d("-------STEP SERVICE-------", "ON REBIND");
		super.onRebind(intent);
	}

	@Override
	public boolean onUnbind(Intent intent) {
		Log.d("-------STEP SERVICE-------", "ON UNBIND");
		return super.onUnbind(intent);
	}

	@Override
	public boolean stopService(Intent name) {
		Log.d("-------STEP SERVICE-------", "ON STOP");
		return super.stopService(name);
	}

	@Override
	public int getDetectorValues(SensorEvent event) {
		float vSum = 0;
		for (int i = 0; i < 3; i++) {
			final float v = mYOffset + event.values[i] * mScale[1];
			vSum += v;
		}
		int k = 0;
		float v = vSum / 3;

		float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1
				: 0));
		if (direction == -mLastDirections[k]) {
			// Direction changed
			int extType = (direction > 0 ? 0 : 1); // minumum or maximum?
			mLastExtremes[extType][k] = mLastValues[k];
			float diff = Math.abs(mLastExtremes[extType][k]
					- mLastExtremes[1 - extType][k]);

			if (diff > mLimit) {

				boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);
				boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);
				boolean isNotContra = (mLastMatch != 1 - extType);

				if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough
						&& isNotContra) {
					Log.d("************STEP DETECTOR************", "ACTION PAS");
					Calendar c = Calendar.getInstance();
					// c.get(Calendar.HOUR);
					Log.d("************STEP DETECTOR************",
							Integer.toString(c.get(Calendar.HOUR_OF_DAY)) + ":"
									+ Integer.toString(c.get(Calendar.MINUTE)));
					/*
					 * if(c.get(Calendar.HOUR_OF_DAY)==0 &&
					 * c.get(Calendar.MINUTE) == 0){ _count = 0; }
					 */
					_count++;
					if (_count % 50 == 0) {
						// ENREGISTREMENT SQLITE DES PAS
						sqlLiteProgressBarDao.open();
						sqlLiteProgressBarDao.updateEvolutionByModule(
								Modules.STEP_COUNTER, 50, 1, new Date(),
								new Date());
						Log.d("************SAVE STEP COUNT************",
								Integer.toString(_count));
					}
					Intent intent2 = new Intent();
					intent2.setAction(MY_ACTION);
					intent2.putExtra("DATAPASSED", _count);
					sendBroadcast(intent2);
					Log.i(TAG, "step:" + Integer.toString(_count));
					mLastMatch = extType;
				} else {
					mLastMatch = -1;
				}
			}
			mLastDiff[k] = diff;
		}
		mLastDirections[k] = direction;
		mLastValues[k] = v;
		return _count;
	}

	public int get_count() {
		return _count;
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void stopDetection() {
		// TODO Auto-generated method stub

	}

	@Override
	public int getDetectorValues(Location location) {
		// TODO Auto-generated method stub
		return 0;
	}

}
